package com.sgzn.sgpay.service.tcp.impl;


import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.sgzn.sgpay.enums.AppName;
import com.sgzn.sgpay.enums.EnumDeviceState;
import com.sgzn.sgpay.enums.EnumLoginCheckResponseResult;
import com.sgzn.sgpay.enums.SgsResponseCode;
import com.sgzn.sgpay.model.request.SgsDeviceQueryRequest;
import com.sgzn.sgpay.model.request.SgsDeviceUpdateRequest;
import com.sgzn.sgpay.model.response.SgsResultResponse;
import com.sgzn.sgpay.model.response.vo.DeviceInfoVo;
import com.sgzn.sgpay.persistence.domain.TDevice;
import com.sgzn.sgpay.persistence.domain.TShop;
import com.sgzn.sgpay.persistence.manager.DeviceDaoManager;
import com.sgzn.sgpay.persistence.manager.ShopDaoManager;
import com.sgzn.sgpay.service.support.SgsResponseUtil;
import com.sgzn.sgpay.service.tcp.SgTcpProtocolHead;
import com.sgzn.sgpay.service.tcp.SgTcpServer;
import com.sgzn.sgpay.service.tcp.api.TcpHeartBeatService;
import com.sgzn.sgpay.service.tcp.model.TcpHeartBeatRequest;
import com.sgzn.sgpay.service.tcp.model.TcpHeartBeatResponse;
import com.sgzn.sgpay.util.SerialNoUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.Socket;
import java.util.Date;
import java.util.List;

/**
 * Created by xxjs-gd-llf
 * DATETIME:2018/4/18 11:44
 * Description:
 */
@Slf4j
@Service
public class TcpHeartBeatServiceImpl implements TcpHeartBeatService {

   /**
     * 心跳服务
     * @param recvBuffer
     * @param socket
     */
    @Override
    public void tcpAnswerHeartBeat(String  recvBuffer, Socket socket){

        TcpHeartBeatRequest tcpHeartBeatRequest = decodeHearBeatBuffer(recvBuffer);

        //检查设备状态
        SgsDeviceQueryRequest sgsDeviceQueryRequest = new SgsDeviceQueryRequest();
        sgsDeviceQueryRequest.setDeviceId(tcpHeartBeatRequest.getDeviceId());
        sgsDeviceQueryRequest.setInitiationID(SerialNoUtil.generateSerialNo(AppName.SGT) );
        sgsDeviceQueryRequest.setReqTime(new Date());
        sgsDeviceQueryRequest.setLoginChannel(AppName.SGT.getNumber());
        //触发AOP日志,如何不触发叱？AOP排除？改调用方法?
        SgsResultResponse<DeviceInfoVo> sgsResultResponse = SgTcpServer.sgsDeviceService.queryDeviceInfo(sgsDeviceQueryRequest);
        if( sgsResultResponse.getResult() != null ){
            if (sgsResultResponse.getResult().getState().equals(EnumDeviceState.OFFLINE.getStateCode())){
                log.info("设备{}未注册",sgsResultResponse.getResult().getDeviceId());
                return;
            }
        }

        SgTcpServer.socketList.put(tcpHeartBeatRequest.getDeviceId(),socket);

        if (tcpHeartBeatRequest != null){
            log.info("维持{} Socket长连接成功",tcpHeartBeatRequest.getDeviceId());
        }
        //回应心跳
        TcpHeartBeatResponse tcpHeartBeatResponse  = handleHeartBeatRequest(tcpHeartBeatRequest);
        try {
//            log.info("发送心跳响应报文:{}",tcpHeartBeatResponse.toString() );
            socket.getOutputStream().write(tcpHeartBeatResponse.toString().getBytes("UTF-8"));
        }catch (IOException e ){
            e.printStackTrace();
        }

        //超时归零
        SgTcpServer.heartBeatCountMap.put(tcpHeartBeatResponse.getDeviceId(),0);

    }

    /**
     * 解析收到的数据
     * @param recvBuffer
     * @return
     */
    private TcpHeartBeatRequest decodeHearBeatBuffer(String recvBuffer){
        TcpHeartBeatRequest tcpHeartBeatRequest = new TcpHeartBeatRequest();

        //命令代码
        tcpHeartBeatRequest.setCommandCode(recvBuffer.split(SgTcpProtocolHead.TCP_PROTOCOL_SEPERATOR)[1] );

        //设备ID
        tcpHeartBeatRequest.setDeviceId( recvBuffer.split(SgTcpProtocolHead.TCP_PROTOCOL_SEPERATOR)[2] );

        //心跳编码
        tcpHeartBeatRequest.setHeartBeatCode(recvBuffer.split(SgTcpProtocolHead.TCP_PROTOCOL_SEPERATOR)[3]);

        //校验和
        tcpHeartBeatRequest.setCheckSumCode(recvBuffer.split(SgTcpProtocolHead.TCP_PROTOCOL_SEPERATOR)[4]);

        //校验和检查
        if(!tcpHeartBeatRequest.getCheckSumCode().equals(SgTcpProtocolHead.DEFAULT_PROTOCOL_CHECKSUM )){

            log.info("校验和错误. {},{}",tcpHeartBeatRequest.getCheckSumCode(),SgTcpProtocolHead.DEFAULT_PROTOCOL_CHECKSUM);
           return  null;
        }
        return  tcpHeartBeatRequest;
    }

    /**
     * 根据请求拼装响应报文
     * @param request
     * @return
     */
    private TcpHeartBeatResponse handleHeartBeatRequest(TcpHeartBeatRequest request ){
        //应答
        TcpHeartBeatResponse tcpHeartBeatResponse = new TcpHeartBeatResponse();
        tcpHeartBeatResponse.setBeginCode(SgTcpProtocolHead.TCP_PROTOCOL_HEAD);
        tcpHeartBeatResponse.setCommandCode(SgTcpProtocolHead.TCP_HEARTBEAT_RESPONSE);
        tcpHeartBeatResponse.setDeviceId( request.getDeviceId() );
        tcpHeartBeatResponse.setHeartBeatCode(request.getHeartBeatCode());
        tcpHeartBeatResponse.setCheckSumCode(SgTcpProtocolHead.DEFAULT_PROTOCOL_CHECKSUM);
        tcpHeartBeatResponse.setEndCode(SgTcpProtocolHead.TCP_PROTOCOL_END);
        return  tcpHeartBeatResponse;
    }



}
